﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 一个线程等待队列中的多个任务通知
{
    public class ProducerConsumerQueue : IDisposable
    {
        EventWaitHandle _ewh = new AutoResetEvent(false);
        private Thread _worker; //等待线程
        private readonly object _locker = new object();
        Queue<string> _tasks = new Queue<string>();//任务队列

        public ProducerConsumerQueue()
        {
            _worker = new Thread(Work);
            _worker.Start();
        }
        //任务进入队列
        public void EnqueueTask(string task)
        {
            lock (_locker)
            {
                _tasks.Enqueue(task);
            }
            //任务一旦进入队列就发出信号
            _ewh.Set();
        }


      

        void Work()
        {
            while (true)
            {
                //从队列中获取task
                string task = null;
                lock (_locker)
                {
                    if (_tasks.Count > 0)
                    {
                        task = _tasks.Dequeue();
                        if (task == null)
                        {
                            return;
                        }
                    }
                }
                //如果task不为null，模拟执行task   当任务出列，就执行任务，执行任务的过程就是所谓的"消费"
                if (task != null)
                {
                    Console.WriteLine("正在执行线程任务 " + task);
                    Thread.Sleep(1000); //模拟线程执行的过程
                }
                else//如果taks为null   在没有task的时候，使用WaitOne方法一直等待；
                {
                    _ewh.WaitOne();//等待信号
                }


            }

        }



        public void Dispose()
        {
            //○ EnqueueTask方法，让任务进入队列，每个进入队列的任务使用Set方法发出通知，产生任务的过程就是所谓的"生产"

            EnqueueTask(null); //发出信号让消费线程退出
            _worker.Join();//让消费线程借宿
            _ewh.Close();//释放event wait handle
        }
    }
}
